package srdb.migration.common;

import srdb.migration.MTKException;
import srdb.migration.dbhandler.db2.DB2TransformDDL;
import srdb.migration.dbhandler.db2.Db2Connection;
import srdb.migration.dbhandler.enterprisedb.EDBSQLServerTransformDDL;
import srdb.migration.dbhandler.enterprisedb.EnterpriseDBConnection;
import srdb.migration.dbhandler.enterprisedb.NZBridge;
import srdb.migration.dbhandler.enterprisedb.NZData;
import srdb.migration.dbhandler.enterprisedb.OfflineData;
import srdb.migration.dbhandler.enterprisedb.RedwoodTransformDDL;
import srdb.migration.dbhandler.mysql.MySQLConnection;
import srdb.migration.dbhandler.redwood.NZTransformDDL;
import srdb.migration.dbhandler.redwood.RedwoodConnection;
import srdb.migration.dbhandler.sqlserver.SQLServerTransformDDL;
import srdb.migration.dbhandler.srdb.SRDBBridge;
import srdb.migration.dbhandler.srdb.SRDBConnection;
import srdb.migration.dbhandler.srdb.PGSQLServerTransformDDL;
import srdb.migration.dbhandler.srdb.SRDBTransformDDL;

public class MTKFactory implements IMTKFactory {
	public MTKData createMTKData(MTKConstants.DATABASE_TYPE databaseType,
			IMTKConnection conn, int cpBatchSize) throws MTKException {
		switch (MTKConstants.DATABASE_TYPE.values()[databaseType.ordinal()]) {
		case SRDB:
			return new srdb.migration.dbhandler.srdb.Data(conn, cpBatchSize);
		case ENTERPRISEDB:
			return new srdb.migration.dbhandler.enterprisedb.Data(conn,
					cpBatchSize);
		case NPS:
			return new NZData(conn, cpBatchSize);
		case ORACLE:
			return new srdb.migration.dbhandler.redwood.Data(conn, cpBatchSize);
		case MYSQL:
			return new srdb.migration.dbhandler.mysql.Data(conn, cpBatchSize,
					databaseType);
		case DB2:
			return new srdb.migration.dbhandler.db2.Data(conn, cpBatchSize);
		case SQLSERVER:
			// case SYBASE:
			return new srdb.migration.dbhandler.sqlserver.Data(conn,
					cpBatchSize, databaseType);
		case OFFLINE:
			return new OfflineData();
		}
		throw new MTKException("The database type is not supported.");
	}

	public MTKMetaData createMTKMetaData(
			MTKConstants.DATABASE_TYPE databaseType, IMTKConnection conn)
			throws MTKException {
		switch (MTKConstants.DATABASE_TYPE.values()[databaseType.ordinal()]) {
		case SRDB:
			try {
				return new srdb.migration.dbhandler.srdb.MetaData(conn);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case DB2:
			try {
				return new srdb.migration.dbhandler.db2.MetaData(conn);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case ENTERPRISEDB:
		case NPS:// n/a
			try {
				return new srdb.migration.dbhandler.enterprisedb.MetaData(conn);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case ORACLE:
			try {
				return new srdb.migration.dbhandler.redwood.MetaData(conn);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case MYSQL:
			try {
				return new srdb.migration.dbhandler.mysql.MetaData(conn);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case SQLSERVER:
			try {
				return new srdb.migration.dbhandler.sqlserver.MetaData(conn);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case SYBASE:
			try {
				return new srdb.migration.dbhandler.sybase.MetaData(conn);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		}
		throw new MTKException("The database type is not supported.");
	}

	public MTKMetaData createMTKMetaData(
			MTKConstants.DATABASE_TYPE databaseType, IMTKConnection conn,
			String targetSchema) throws MTKException {
		switch (MTKConstants.DATABASE_TYPE.values()[databaseType.ordinal()]) {
		case SRDB:
			try {
				return new srdb.migration.dbhandler.srdb.MetaData(conn,
						targetSchema);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case DB2:
			try {
				return new srdb.migration.dbhandler.db2.MetaData(conn,
						targetSchema);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case NPS:// n/a
		case ENTERPRISEDB:
			try {
				return new srdb.migration.dbhandler.enterprisedb.MetaData(conn,
						targetSchema);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case ORACLE:
			try {
				return new srdb.migration.dbhandler.redwood.MetaData(conn,
						targetSchema);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case SYBASE:
			try {
				return new srdb.migration.dbhandler.sybase.MetaData(conn,
						targetSchema);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case MYSQL:
			try {
				return new srdb.migration.dbhandler.mysql.MetaData(conn,
						targetSchema);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case SQLSERVER:
			try {
				return new srdb.migration.dbhandler.sqlserver.MetaData(conn,
						targetSchema);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		}
		throw new MTKException("The database type is not supported.");
	}

	public MTKBridge createMTKBridge(MTKConstants.DATABASE_TYPE sourceDBType,
			MTKConstants.DATABASE_TYPE targetDBType, IMTKConnection srcConn,
			IMTKConnection targetConn) throws MTKException {
		MTKBridge result = null;

		if (targetDBType == MTKConstants.DATABASE_TYPE.OFFLINE) {
			return new MTKOfflineBridge(srcConn);
		}

		if ((sourceDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
				|| (sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE)
				|| (sourceDBType == MTKConstants.DATABASE_TYPE.SRDB))
			;
		switch (MTKConstants.DATABASE_TYPE.values()[targetDBType.ordinal()]) {
		case SRDB:
			result = new SRDBBridge(srcConn, targetConn);
			break;
		// case SYBASE:// n/a
		// result = new RedwoodBridge(srcConn, targetConn);
		// break;
		case NPS:
			result = new NZBridge(srcConn, targetConn);
			break;
		case ORACLE:
			result = new srdb.migration.dbhandler.redwood.EDBBridge(srcConn,
					targetConn);
			break;
		case SQLSERVER:
			result = new srdb.migration.dbhandler.sqlserver.EDBBridge(srcConn,
					targetConn);
			break;
//		case DB2:
//			// case NPS:
//			new MTKGenericBridge(srcConn, targetConn, sourceDBType,
//					targetDBType);
		default:
			throw new MTKException("The database type is not supported.");

			// if ((sourceDBType != MTKConstants.DATABASE_TYPE.MYSQL)
			// && (sourceDBType != MTKConstants.DATABASE_TYPE.SYBASE)
			// && (sourceDBType != MTKConstants.DATABASE_TYPE.SQLSERVER)) {
			// break;
			// }
			// switch
			// (MTKConstants.DATABASE_TYPE.values()[targetDBType.ordinal()]) {
			// case 2:
			// result = new MTKGenericBridge(srcConn, targetConn,
			// sourceDBType, targetDBType);
			// break;
			// case 1:
			// result = new MTKGenericBridge(srcConn, targetConn,
			// sourceDBType, targetDBType);
			// break;
			// default:
			// throw new MTKException("The database type is not supported.");
			// }
		}
		return result;
	}

	/**
	 * 根据源数据类型 和 目标数据库类型 定义不同的 MTKTransformDDL类。
	 * 迁移过程里schema或者table等等的创建，都是基于MTKTransformDDL来生成ddl语句
	 */
	public MTKTransformDDL createMTKTransformDDL(
			MTKConstants.DATABASE_TYPE sourceDBType,
			MTKConstants.DATABASE_TYPE targetDBType) throws MTKException {
		if ((sourceDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
				&& (targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)) {
			return new srdb.migration.dbhandler.enterprisedb.EDBTransformDDL();
		}
		if ((sourceDBType == MTKConstants.DATABASE_TYPE.SRDB)
				&& (targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)) {
			return new SRDBTransformDDL();
		}
		if ((sourceDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
				&& (targetDBType == MTKConstants.DATABASE_TYPE.ORACLE))
			return new RedwoodTransformDDL();
		if ((sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE)
				&& (targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB))
			return new srdb.migration.dbhandler.redwood.EDBTransformDDL();
		if ((sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE)
				&& (targetDBType == MTKConstants.DATABASE_TYPE.NPS))
			return new NZTransformDDL();
		if ((sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE)
				&& (targetDBType == MTKConstants.DATABASE_TYPE.SRDB))
			return new srdb.migration.dbhandler.redwood.PGTransformDDL();
		if (((sourceDBType == MTKConstants.DATABASE_TYPE.SRDB) || (sourceDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB))
				&& (targetDBType == MTKConstants.DATABASE_TYPE.SRDB)) {
			return new SRDBTransformDDL();
		}
		if ((sourceDBType == MTKConstants.DATABASE_TYPE.SQLSERVER)
				&& (targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB))
			return new SQLServerTransformDDL();
		if ((sourceDBType == MTKConstants.DATABASE_TYPE.SQLSERVER)
				&& (targetDBType == MTKConstants.DATABASE_TYPE.SRDB))
			return new SQLServerTransformDDL();
		if ((sourceDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
				&& (targetDBType == MTKConstants.DATABASE_TYPE.SQLSERVER))
			return new EDBSQLServerTransformDDL();
		if ((sourceDBType == MTKConstants.DATABASE_TYPE.SRDB)
				&& (targetDBType == MTKConstants.DATABASE_TYPE.SQLSERVER))
			return new PGSQLServerTransformDDL();
		if ((sourceDBType == MTKConstants.DATABASE_TYPE.DB2)
				&& (targetDBType == MTKConstants.DATABASE_TYPE.SRDB)) {
			return new DB2TransformDDL();
		}
		if (((sourceDBType == MTKConstants.DATABASE_TYPE.MYSQL) || (sourceDBType == MTKConstants.DATABASE_TYPE.SYBASE))
				&& ((targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) || (targetDBType == MTKConstants.DATABASE_TYPE.SRDB))) {
			return new MTKGenericTransformDDL();
		}
		throw new MTKException("The database type is not supported.");
	}

	public IMTKConnection createMTKConnection(
			MTKConstants.DATABASE_TYPE dbType, String dbURL, String dbUser,
			String dbPassword) throws MTKException {
		switch (MTKConstants.DATABASE_TYPE.values()[dbType.ordinal()]) {
		case DB2:
			try {
				return new Db2Connection(dbURL, dbUser, dbPassword);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case SRDB:
			try {
				return new SRDBConnection(dbURL, dbUser, dbPassword);
			} catch (Exception e) {
				throw new MTKException(e);
			}
			// case 2:
		case ENTERPRISEDB:
			try {
				return new EnterpriseDBConnection(dbURL, dbUser, dbPassword);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case ORACLE:
			try {
				return new RedwoodConnection(dbURL, dbUser, dbPassword);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case MYSQL:
			try {
				return new MySQLConnection(dbURL, dbUser, dbPassword);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case SQLSERVER:
			try {
				return new JTDSConnection(dbURL, dbUser, dbPassword);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case SYBASE:
			try {
				return new JTDSConnection(dbURL, dbUser, dbPassword);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		}
		throw new MTKException("The database type is not supported.");
	}

	public IMTKConnection createMTKConnection(
			MTKConstants.DATABASE_TYPE dbType, String propertiesFile)
			throws MTKException {
		switch (MTKConstants.DATABASE_TYPE.values()[dbType.ordinal()]) {
		case DB2:
			try {
				return new Db2Connection(propertiesFile);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case SRDB:
			try {
				return new SRDBConnection(propertiesFile);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case ENTERPRISEDB:
			// case 3:
			try {
				return new EnterpriseDBConnection(propertiesFile);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case ORACLE:
			try {
				return new RedwoodConnection(propertiesFile);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case MYSQL:
			try {
				return new MySQLConnection(propertiesFile);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case SYBASE:
			try {
				return new JTDSConnection(propertiesFile);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		case SQLSERVER:
			try {
				return new JTDSConnection(propertiesFile);
			} catch (Exception e) {
				throw new MTKException(e);
			}
		}
		throw new MTKException("The database type is not supported.");
	}
}

/*

 */